package com.david.rocket.service;

import com.david.rocket.common.Const;
import com.david.rocket.dao.GoodsRepository;
import com.david.rocket.dao.OrderRepository;
import com.david.rocket.entity.OrderEntity;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.IntStream;

import static com.david.rocket.common.Const.REDIS_GOODS_KEY;

@Service
public class SpikeService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private GoodsRepository goodsRepository;
    @Autowired
    private OrderRepository orderRepository;

    //初始化库存
    @PostConstruct
    public void init() {
        ListOperations<String, String> ops = redisTemplate.opsForList();
        goodsRepository.findAll().forEach(g -> {
            String key = genKey(String.valueOf(g.getId()));
            redisTemplate.delete(key);
            //生成count个uuid 作为订单唯一id
            IntStream.range(0, Math.toIntExact(g.getNum())).forEach(i -> {
                ops.leftPush(key, UUID.randomUUID().toString());
            });
        });
    }

    public String genKey(String goodsId) {
        return REDIS_GOODS_KEY + goodsId;
    }

    //模拟付款成功
    public OrderEntity pay(String orderId) {
        Optional<OrderEntity> o = orderRepository.findOrderEntitiesByOrderId(orderId);
        if (o.isPresent()) {
            OrderEntity entity = o.get();
            if (Const.OrderStatue.valueOf(entity.getStatus()) == Const.OrderStatue.canceled) {
                throw new RuntimeException("订单已取消");
            }
            entity.setStatus(Const.OrderStatue.success.name());
            orderRepository.save(entity);
            return entity;
        }
        return null;
    }

    //秒杀业务逻辑
    public String spike(String goodsId) {
        ListOperations<String, String> ops = redisTemplate.opsForList();
        String key = genKey(goodsId);
        Long size = ops.size(key);
        if (size == null || size <= 0) {
            return "没库存了";
        }
        String orderId = ops.leftPop(key);
        if (orderId == null || "".equals(orderId)) {
            return "秒杀失败";
        }
        //异步生成订单
        rocketMQTemplate.convertAndSend(Const.TOPIC_ORDER_CREATE, orderId + "_" + goodsId);
        //发送延时消息 检查订单状态
        Message<String> message = MessageBuilder.withPayload(orderId).build();
//        "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h"; 1--->18
        rocketMQTemplate.syncSend(Const.TOPIC_ORDER_CHECK, message, 20_000, 4);
        return orderId;
    }
}
